﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using InductBase;
using InductBase.Extensions;

namespace PowerOne.GraphicUtilites
{

    public class BitmapAtlas
    {
        static int number = 0;

        public Bitmap Bitmap;
        public int ShiftX;
        public int ShiftY;
        public Vec2 Size { get; private set; }
        public Texture Texture { get; private set; }
        public List<Bitmap> Bitmaps { get; private set; }
        public bool IsBaked { get; private set; }

        List<Rec> Recs;

        public BitmapAtlas()
        {
            Bitmaps = new List<System.Drawing.Bitmap>();
            Bitmap = new Bitmap(1024*4, 1024*4);
            Size = Bitmap.Size.ToVec2();
            ShiftX = 0;
            ShiftY = 0;
            Recs = new List<Rec>();

            IsBaked = false;
        }

        public Rec AddBitmap(Bitmap bmp)
        {
            IsBaked = false;


            Rec result = new Rec(0, 0, bmp.Width, bmp.Height);

            bool solved = false;

            List<int> ixs = Recs.ConvertAll(p => (int)p.Right);
            ixs.Sort();
            ixs.Insert(0, 0);

            List<int> iys = Recs.ConvertAll(p => (int)p.Bottom);
            iys.Sort();
            iys.Insert(0, 0);

            foreach (int i in ixs)
            {
                foreach (int j in iys)
                {
                
                    result.Location = new Vec2(i+1, j+1);
                    if (result.Right > Size.X || result.Bottom > Size.Y)
                        continue;

                    Rec rec = Recs.Find(p => p.Intersects(result));
                    if (rec != null)
                    {                       
                        continue;
                    }

                    solved = true;
                    break;
                }

                if (solved) break;
            }

            if (result.Right > Size.X || result.Bottom > Size.Y)
            {
#if DEBUG
                BakeAtlas();
                Bitmap.Save(String.Format("atlas{0}.png", number++));
#endif
                throw new ArgumentOutOfRangeException("bmp", "Atlas bitmap is filled");
            }

            Bitmaps.Add(bmp);
            Recs.Add(result.Copy());
            return result;
        }

        public void BakeAtlas()
        {
            Bitmap = new Bitmap(Bitmap.Width, Bitmap.Height);
            Graphics g = Graphics.FromImage(Bitmap);

            for (int i = 0; i < Bitmaps.Count; i++)
            {
                Bitmap bmp = Bitmaps[i];
                Rec result = Recs[i];

                bmp.SetResolution(g.DpiX, g.DpiY);

                g.DrawImageUnscaled(
                    bmp,
                    result.Location.ToPoint());
            }

            g.Dispose();

            if (Texture != null)
            {
                Texture.Dispose();
                Texture = null;
            }

            Texture = new Texture(Bitmap, OpenGLRender.CurrentFilter);
            IsBaked = true;
        }
    }
}
